package com.vecspace.database.dao;

import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import com.vecspace.database.model.QuerySQL;
import com.vecspace.exception.HException;
import com.vecspace.utils.FileHelper;
import com.vecspace.utils.XmlUtils;

import comvecspace.data.model.sql.SqlCache;

import java.util.List;

public class DaoUtil {
	//private static Logger logger = LoggerFactory.getLogger(DaoUtil.class);
	
	public static String getSql(Class<?> clazz, String id) throws Exception{
		String sqlKey = clazz.getName()+":"+id;
		String sql = SqlCache.DEFAULT().get(sqlKey);
		if(sql == null){
			synchronized (clazz) {
				sql = SqlCache.DEFAULT().get(sqlKey);
				if(sql == null){
					String fileName = clazz.getName().replace(".", "/");
					if(fileName.endsWith("Dao")){
						fileName = fileName.substring(0,fileName.length()-3);
					}
					fileName = fileName+".sql.xml";
					String xml = FileHelper.readFileText(clazz, fileName);
					if(xml != null && xml.length()>0){
					   Document document = DocumentHelper.parseText(xml);
					   Node node = document.selectSingleNode("/sqllist/sql[@id='"+id+"']");
					   if(node != null){
						   sql = node.getText();
					   }
					}else{
						throw new HException("没有读取到文件："+fileName);
					}
					if(sql != null && sql.trim().length()>0){
						SqlCache.DEFAULT().put(sqlKey, sql.trim());
					}
				}
			}
		}
		return sql;
	}
	
	/**读取 QuerySQL 对象
	 * 
	 * @param clazz
	 * @param id
	 * @return
	 * @throws Exception 
	 * @author wanghua
	 * @reviewer  
	 * @createTime 2021年9月30日 上午9:09:20
	 */
	public static QuerySQL getQuerySql(Class<?> clazz, String id) throws Exception{
		String sqlKey = clazz.getName()+":"+"querysql:"+id;
		QuerySQL querySql = SqlCache.DEFAULT().getQuerySQL(sqlKey);
		if(querySql == null){
			synchronized (clazz) {
				querySql = SqlCache.DEFAULT().getQuerySQL(sqlKey);
				if(querySql == null){
					querySql = new QuerySQL();
					String fileName = clazz.getName().replace(".", "/");
					if(fileName.endsWith("Dao")){
						fileName = fileName.substring(0,fileName.length()-3);
					}
					fileName = fileName+".sql.xml";
					String xml = FileHelper.readFileText(clazz, fileName);
					if(xml != null && xml.length()>0){
					   Document document = DocumentHelper.parseText(xml);
					   Node node = document.selectSingleNode("/sqllist/sql[@id='"+id+"']");
					   if(node != null){
						   querySql.setCteSql(XmlUtils.readChildInnerText(node, "cte"));
						   querySql.setQueryColumns(XmlUtils.readChildInnerText(node, "select"));
						   querySql.setTables(XmlUtils.readChildInnerText(node, "from"));
						   querySql.setWhere(XmlUtils.readChildInnerText(node, "where"));
						   querySql.setOrderby(XmlUtils.readChildInnerText(node, "orderby"));
						   Element orderbyNode = (Element)node.selectSingleNode("orderby");
						   if(orderbyNode != null) {
							   boolean siblings = "true".equalsIgnoreCase(orderbyNode.attributeValue("siblings"));
							   querySql.setOrderSiblings(siblings);
						   }
						   List<Node> groupNodes = node.selectNodes("group");
						   if(groupNodes != null && groupNodes.size() > 0){
								for(Node groupNode : groupNodes){
									Element groupElement = (Element)groupNode;
									String groupName = groupElement.attributeValue("name");
									String groupLabel = groupElement.attributeValue("label");
									String groupColumns = XmlUtils.readChildInnerText(groupNode, "groupColumns");
									String aggregateColumns = XmlUtils.readChildInnerText(groupNode, "aggregateColumns");
									querySql.addQueryGroup(groupName, groupLabel, groupColumns, aggregateColumns);
								}
						   }else{
							   String groupColumns = XmlUtils.readChildInnerText(node, "groupColumns");
							   String aggregateColumns = XmlUtils.readChildInnerText(node, "aggregateColumns");
							   if(StringUtils.isNotBlank(groupColumns)) {
								   querySql.addQueryGroup(null, null, groupColumns, aggregateColumns);
							   }
						   }
					   }
					}else{
						throw new HException("没有读取到文件："+fileName);
					}
					
					SqlCache.DEFAULT().put(sqlKey, querySql);
				}
			}
		}
		return querySql.clone();//不能直接返回querySql，因为在外部修改后，再次使用时就不时最开始的值了。
	}
	
}
